﻿#include "MySqlConn.h"
#include <iostream>

// 初始化数据库的连接
MySqlConn::MySqlConn()
{
	m_conn = mysql_init(NULL);
	mysql_set_character_set(m_conn, "utf8");
}

// 释放数据库的连接
MySqlConn::~MySqlConn()
{
	if (m_conn != nullptr) {
		mysql_close(m_conn);
	}
	freeResult();
}

bool MySqlConn::connect(std::string username, std::string password, std::string dbname, std::string ip, unsigned short port)
{
	MYSQL* ptr = mysql_real_connect(m_conn, ip.c_str(), username.c_str(), password.c_str(), dbname.c_str(),  port, NULL, 0);

	return ptr != nullptr;
}

// 更新数据库 insert update delete
bool MySqlConn::update(std::string sql)
{
	if (mysql_query(m_conn, sql.c_str())) {
		return false;
	}

	return true;
}

// 查询数据库
bool MySqlConn::query(std::string sql)
{
	freeResult();
	if (mysql_query(m_conn, sql.c_str()) != 0) {
		std::cout << "Query error: " << mysql_error(m_conn) << std::endl;
		return false;
	}
	m_res = mysql_store_result(m_conn); // 保存查询的结果集

	return true;
}

// 遍历得到的结果集
bool MySqlConn::next()
{
	if (m_res != nullptr) { 
		// 得到表的行集合
		m_row = mysql_fetch_row(m_res);
		if (m_row != nullptr) {
			return true;
		}
	}

	return false;
}

// 得到结果集中的字段
std::string MySqlConn::value(int index)
{
	// 获取结果集中的总列数
	int fieldCount = mysql_num_fields(m_res);
	if (index >= fieldCount || index < 0) {
		return std::string();
	}
	
	// 获取一行中的一个字段 
	char* val = m_row[index];
	// 获取index字段数据的字节长度，保证char* -> string 不会出现问题(防止二进制数据转换出现问题)
	unsigned long length = mysql_fetch_lengths(m_res)[index];
	return std::string(val, length);
}

// 事务操作
bool MySqlConn::transcation()
{
	// 关闭自动提交事务 auto-mode : 1 自动提交事务		0 手动提交事务
	return mysql_autocommit(m_conn, 0);
}

// 提交事务
bool MySqlConn::commit()
{
	return mysql_commit(m_conn);
}

// 事务回滚
bool MySqlConn::rollback()
{
	return mysql_rollback(m_conn);
}

void MySqlConn::freeResult()
{
	if (m_res) {
		mysql_free_result(m_res);
		m_res = nullptr;
	}
}

// 刷新起始的空闲时间点
void MySqlConn::refreshAliveTime()
{
	// 获取当前的时间点
	m_alivetime = std::chrono::steady_clock::now();
}

// 计算连接时长
long long MySqlConn::getAliveTime()
{
	std::chrono::nanoseconds res = std::chrono::steady_clock::now() - m_alivetime;
	// 计算连接存活的时间
	std::chrono::microseconds millsec = std::chrono::duration_cast<std::chrono::milliseconds>(res);

	// 获取std::chrono::milliseconds类型对象所代表的时间长度值，以整数形式表达毫秒数
	return millsec.count();
}

